﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Zy.Shared.Constraint.Dtos;
using Zy.Shared.Constraint.IServices;
using Zy.Shared.Rpc.GrpcBase;
using Zy.Shared.Nacos;
using Nacos.V2;
using Grpc.Net.ClientFactory;
using Microsoft.Extensions.Options;

namespace Zy.Shared.Rpc.Registers
{
    public static class RegisterGrpcService
    {
        /// <summary>
        /// 添加Grpc服务
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddZyGrpcService(this IServiceCollection services,IConfiguration configuration)    
        {
            services.AddGrpc(options =>
            {               
                //options.Interceptors.Add<GrpcAuthInterceptor>();
            });
            #region gRPC Client注册
            AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
            services.AddGrpcClient<UserGrpc.UserGrpcClient>(options =>
            {
                options.Address = new Uri(GetGrpcClientUrl(services, configuration, "user"));
              
            }).AddCallCredentials((context, metadata, serviceProvider) =>
                {
                    var user = serviceProvider?.GetService<ZyUserContext>();
                    var _token = user?.Token;
                    if (!string.IsNullOrEmpty(_token))
                    {
                        metadata.Add("Authorization", $"Bearer {_token}");
                    }
                    return Task.CompletedTask;
                }).ConfigureChannel(grpcOptions =>
            {
                //可以完成各种配置，比如token
                //TODO:配置TOKEN
                grpcOptions.HttpClient?.DefaultRequestHeaders?.Add("Z-type", "grpc");
                grpcOptions.UnsafeUseInsecureChannelCallCredentials = true;

            });
            services.AddGrpcClient<Hello.HelloClient>(options =>
            {
                options.Address = new Uri(GetGrpcClientUrl(services, configuration,"user"));
            })
               .AddCallCredentials((context, metadata, serviceProvider) =>
               {
                   var user = serviceProvider?.GetService<ZyUserContext>();
                   var _token = user?.Token;
                   if (!string.IsNullOrEmpty(_token))
                   {
                       metadata.Add("Authorization", $"Bearer {_token}");
                   }
                   return Task.CompletedTask;
               }).ConfigureChannel(grpcOptions =>
               {
                   //可以完成各种配置，比如token
                   //TODO:配置TOKEN
                   grpcOptions.HttpClient?.DefaultRequestHeaders?.Add("Z-type", "grpc");
                   grpcOptions.UnsafeUseInsecureChannelCallCredentials = true;

               });

            #endregion
            #region 注册Client的Service
            var serviceTypes = Assembly.GetExecutingAssembly()?
                .GetExportedTypes()
                .Where(type => type.IsClass && type.GetInterfaces().Contains(typeof(IGrpcBaseClientService)))
                .ToList();
            serviceTypes.ForEach(serviceType =>
            {
                services.AddScoped(serviceType);
            });
            #endregion
            return services;
        }
        /// <summary>
        /// // 获取gRPC服务地址
        /// </summary>
        /// <param name="services"></param>
        /// <param name="configuration"></param>
        /// <param name="serviceName"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        private static string GetGrpcClientUrl(IServiceCollection services, IConfiguration configuration,string serviceName)
        {
            var namingClient = services.BuildServiceProvider().GetRequiredService<INacosNamingService>();

            // 查询 Nacos 中注册的 gRPC 服务地址
            var instances = namingClient.GetAllInstances(serviceName, configuration.GetValue<string>("NacosConfig:GroupName")).Result;

            if (instances.Count > 0)
            {
                var selectedInstance = instances.Random(); // 随机选择一个实例
                var serviceUrl = $"https://{selectedInstance.Ip}:{selectedInstance.Port}";
                return serviceUrl;
            }
            else
            {
                throw new Exception("No available gRPC service instances found.");
            }
        }
    }
}
